package com.zhang.gulimall.ware.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rabbitmq.client.Channel;
import com.zhang.gulimall.common.to.SkuHasStockTo;
import com.zhang.gulimall.common.to.mq.StockLockedTo;
import com.zhang.gulimall.common.utils.R;
import com.zhang.gulimall.ware.entity.WareOrderTaskDetailEntity;
import com.zhang.gulimall.ware.entity.WareOrderTaskEntity;
import com.zhang.gulimall.ware.feign.OrderServiceFeign;
import com.zhang.gulimall.ware.service.WareOrderTaskDetailService;
import com.zhang.gulimall.ware.service.WareOrderTaskService;
import com.zhang.gulimall.ware.vo.OrderItemEntity;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhang.gulimall.common.utils.PageUtils;
import com.zhang.gulimall.common.utils.Query;

import com.zhang.gulimall.ware.dao.WareSkuDao;
import com.zhang.gulimall.ware.entity.WareSkuEntity;
import com.zhang.gulimall.ware.service.WareSkuService;
import org.springframework.transaction.annotation.Transactional;


@RabbitListener(queues = "stock.release.stock.queue")
@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Autowired
    OrderServiceFeign orderServiceFeign;
    @Autowired
    WareOrderTaskService wareOrderTaskService;
    @Autowired
    WareOrderTaskDetailService wareOrderTaskDetailService;
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                new QueryWrapper<WareSkuEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageByParams(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> wrapper = new QueryWrapper<>();
        String wareId = (String) params.get("wareId");
        String skuId = (String) params.get("skuId");
        if (!wareId.isEmpty()) {
            wrapper.lambda().eq(WareSkuEntity::getWareId, wareId);
        }
        if (!wareId.isEmpty()) {
            wrapper.lambda().eq(WareSkuEntity::getSkuId, skuId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<SkuHasStockTo> hasStock(List<String> ids) {
        return ids.stream().map(id -> {
            SkuHasStockTo skuHasStockTo = new SkuHasStockTo();
            int count = 0;
            try {
                count = baseMapper.getSkuStock(id);
            } catch (NullPointerException e) {
                System.out.println("未查询到库存记录");
            }
            skuHasStockTo.setSkuId(id);
            skuHasStockTo.setHasStock(count > 0);
            return skuHasStockTo;
        }).collect(Collectors.toList());
    }

    @Transactional
    @Override
    public Boolean lockOrder(List<OrderItemEntity> orderItems) {
        // 保存库存工作单
        WareOrderTaskEntity wareOrderTaskEntity = new WareOrderTaskEntity();
        wareOrderTaskEntity.setOrderSn(orderItems.get(0).getOrderSn());
        wareOrderTaskEntity.setOrderId(orderItems.get(0).getOrderId());
        wareOrderTaskEntity.setTaskStatus(0);
        wareOrderTaskService.save(wareOrderTaskEntity);

        List<String> collect = orderItems.stream().map(OrderItemEntity::getSkuId).collect(Collectors.toList());
        Map<String, OrderItemEntity> map = orderItems.stream().collect(Collectors.toMap(OrderItemEntity::getSkuId, orderItem -> orderItem));
        // 获取仓库记录
        List<WareSkuEntity> list = this.list(new LambdaQueryWrapper<WareSkuEntity>().in(WareSkuEntity::getSkuId, collect));
        // todo 多地库存逻辑
//        Map<String, WareSkuEntity> map1 = new HashMap<>();
//        // 计算所有仓库的总库存
//        for (WareSkuEntity ware : list) {
//            if (map1.size() >= 1) {
//                WareSkuEntity entity = map1.get(ware.getSkuId());
//                ware.setStockLocked(ware.getStockLocked()+entity.getStockLocked());
//                continue;
//            }
//            map1.put(ware.getSkuId(), ware);
//        }
//        // 判断是否有库存
//        List<WareSkuEntity> list1 = new ArrayList<>(map1.values());
//        map.forEach((key,ware)->{
//
//        });
        List<WareOrderTaskDetailEntity> wareOrderTaskDetailEntities = new ArrayList<>();
        for (WareSkuEntity wareSkuEntity : list) {
            OrderItemEntity orderItemEntity = map.get(wareSkuEntity.getSkuId());
            int lock = wareSkuEntity.getStockLocked() + orderItemEntity.getSkuQuantity();
            if (wareSkuEntity.getStock() < lock) {
                return false;
            }
            wareSkuEntity.setStockLocked(lock);

            WareOrderTaskDetailEntity wareOrderTaskDetailEntity = new WareOrderTaskDetailEntity("",
                    orderItemEntity.getSkuId(), orderItemEntity.getSkuName(), orderItemEntity.getSkuQuantity(),
                    wareOrderTaskEntity.getId(), wareSkuEntity.getWareId(), 1);

            wareOrderTaskDetailEntities.add(wareOrderTaskDetailEntity);
        }
        this.updateBatchById(list);
        wareOrderTaskDetailService.saveBatch(wareOrderTaskDetailEntities);
        // 发送库存锁定消息
        rabbitTemplate.convertAndSend("stock-event-exchange", "stock.locked", orderItems.get(0).getOrderSn());
        return true;
    }

    // 库存解锁
    @RabbitHandler
    public void handleStockLockedRelease(String orderSn, Message message, Channel channel) throws IOException {
        // 获取工作单实体
        WareOrderTaskEntity taskEntity = wareOrderTaskService.getOne(
                new LambdaQueryWrapper<WareOrderTaskEntity>().eq(WareOrderTaskEntity::getOrderSn, orderSn));
        // 获取订单状态
        R orderStatus = orderServiceFeign.getOrderStatus(taskEntity.getOrderSn());
        if (orderStatus.getCode() == 0) {   // 判断远程是否成功
            String status = JSON.toJSONString(orderStatus.get("data"));
            // 判断订单状态
            if (status.equals("4") || status.equals("null")) {
                // 获取工作单细节
                List<WareOrderTaskDetailEntity> taskDetailEntities = wareOrderTaskDetailService.list(
                        new LambdaQueryWrapper<WareOrderTaskDetailEntity>().eq(WareOrderTaskDetailEntity::getTaskId, taskEntity.getId()));
                Map<String, WareOrderTaskDetailEntity> map = taskDetailEntities.stream().collect(Collectors.toMap(WareOrderTaskDetailEntity::getWareId, entity -> entity));
                List<String> wareIds = taskDetailEntities.stream().filter(e -> e.getLockStatus() == 1).map(WareOrderTaskDetailEntity::getWareId).collect(Collectors.toList());
                if (wareIds.size() > 0) {
                    List<WareSkuEntity> wareSkuEntities = this.list(new QueryWrapper<WareSkuEntity>().lambda().in(WareSkuEntity::getWareId, wareIds));
                    // 修改库存锁定
                    for (WareSkuEntity wareSkuEntity : wareSkuEntities) {
                        wareSkuEntity.setStockLocked(wareSkuEntity.getStockLocked() - map.get(wareSkuEntity.getWareId()).getSkuNum());
                    }
                    // 更新库存锁定
                    this.updateBatchById(wareSkuEntities);
                    // 更新订单细节锁定状态
                    for (WareOrderTaskDetailEntity taskDetailEntity : taskDetailEntities) {
                        taskDetailEntity.setLockStatus(2);
                    }
                    wareOrderTaskDetailService.updateBatchById(taskDetailEntities);
                }
            }
        } else {
            // 拒绝消息重新放回队列
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
            return;
        }
        System.out.println("库存解锁成功");
        // 成功,删除消息
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}